﻿using Frame.Core.Models;
using FreeSql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Frame.Core.Repository
{
    public  class RepositoryBase<TEntity> : DefaultRepository<TEntity, int>, IRepositoryBase<TEntity> where TEntity : class, new()
    {
        readonly IFreeSql _freeSql;
        public RepositoryBase(UnitOfWorkManager uowm) : base(uowm?.Orm, uowm)
        {
            _freeSql = uowm.Orm;
        }


        #region 仓储方法

        public async Task<TEntity> GetLeftJoinAsync(Expression<Func<TEntity, bool>> leftJoinExpression, Expression<Func<TEntity, bool>> exp)
        {
            return await Select.Where(exp).LeftJoin(leftJoinExpression).ToOneAsync();
        }

        public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> exp)
        {
            return await Select.Where(exp).ToOneAsync();
        }

        public async Task<TDto> GetAsync<TDto>(Expression<Func<TEntity, bool>> exp)
        {
            return await Select.Where(exp).ToOneAsync<TDto>();
        }

        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> exp)
        {
            return await Select.WhereIf(exp!=null,exp).ToListAsync();
        }


        public async Task<TEntity> AddAsync(TEntity entity)
        {
            return await InsertAsync(entity);
        }

        public async Task<IEnumerable<TEntity>> AddAsync(IEnumerable<TEntity> entitys)
        {
            return await InsertAsync(entitys);
        }

        public async Task<int> EditAsync(TEntity entity)
        {
            return await UpdateAsync(entity);
        }
        public async Task<int> EditSingeColumnAsync(Expression<Func<TEntity, object>> setExpression,Expression<Func<TEntity, bool>> exp)
        {
            return await _freeSql.Update<TEntity>().SetIf(setExpression!=null, setExpression).WhereIf(exp!=null, exp).ExecuteAffrowsAsync();
        }
        public async Task<int> AttachEditAsync(TEntity oldobj, TEntity newObj)
        {
            Attach(oldobj);
            oldobj = newObj;
            return await UpdateAsync(oldobj);
        }

        public async Task<int> DelAsync(Expression<Func<TEntity, bool>> exp)
        {
            return await DeleteAsync(exp);
        }

        public  async Task<PagingInfoViewModel<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, PagingInfoViewModel<TEntity> pageInfo, Expression<Func<TEntity, TEntity>> includeExpression=null)
        {
            //设置查询条件
            pageInfo.List = await Select.OrderByPropertyNameIf(pageInfo.SortField != null, pageInfo.SortField, pageInfo.Descending).OrderBy(pageInfo.PageKey)
                .IncludeIf(includeExpression != null, includeExpression)
                .WhereIf(whereExpression != null, whereExpression)
                .Count(out var total)
                .Page(pageInfo.PageIndex, pageInfo.PageSize)
                .ToListAsync();
            pageInfo.Count = total;
            return pageInfo;
        }

        #endregion


        #region Ado方法
        public async Task<int> AdoExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms)
        {
            return await _freeSql.Ado.ExecuteNonQueryAsync(cmdType, cmdText, cmdParms);
        }
        public async Task<int> AdoExecuteNonQueryAsync(string cmdText, object parms=null)
        {
            return await _freeSql.Ado.ExecuteNonQueryAsync(cmdText,parms);
        }
        #endregion
        ///// <summary>
        ///// 新增方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public async virtual Task<TEntity> InsertAsync(TEntity model)
        //{
        //    var repo = _freeSql.GetRepository<TEntity>();
        //    await repo.InsertAsync(model);
        //    return model;
        //}

        ///// <summary>
        ///// 新增方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public async virtual Task<int> BatchInsertAsync(List<T> models)
        //{
        //    var runsql = DbType.DB().Insert<T>().AppendData(models);
        //    return await runsql.ExecuteAffrowsAsync();
        //}

        ///// <summary>
        ///// 修改方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public async virtual Task<bool> UpdateAsync(T model)
        //{
        //    var runsql = DbType.DB().Update<T>().SetSource(model);
        //    var rows = await runsql.ExecuteAffrowsAsync();
        //    return rows > 0;
        //}

        ///// <summary>
        ///// 删除方法
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public async virtual Task<bool> DeleteAsync(long id)
        //{
        //    var result = await DbType.DB().Delete<T>(id).ExecuteAffrowsAsync();
        //    return result > 0;
        //}

        ///// <summary>
        ///// 删除方法
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public virtual bool Delete(Expression<Func<T, bool>> where)
        //{
        //    var result = DbType.DB().Delete<T>().Where(where).ExecuteAffrows();
        //    return result > 0;
        //}

        ///// <summary>
        ///// 删除方法
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public async virtual Task<bool> DeleteAsync(Expression<Func<T, bool>> where)
        //{
        //    var result = await DbType.DB().Delete<T>().Where(where).ExecuteAffrowsAsync();
        //    return result > 0;
        //}

        ///// <summary>
        ///// 获取一条数据
        ///// </summary>
        ///// <param name="where"></param>
        ///// <returns></returns>
        //public async virtual Task<T> GetByOneAsync(Expression<Func<T, bool>> where)
        //{
        //    return await DbType.DB().Select<T>()
        //        .Where(where).ToOneAsync();
        //}



        //#region no Async

        ///// <summary>
        ///// 新增方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public virtual long Count()
        //{
        //    var runsql = DbType.DB().Select<T>();
        //    return runsql.Count();
        //}

        ///// <summary>
        ///// 新增方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public virtual long Insert(T model)
        //{
        //    var runsql = DbType.DB().Insert<T>(model);
        //    return runsql.ExecuteIdentity();
        //}

        ///// <summary>
        ///// 新增方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public virtual int BatchInsert(List<T> models)
        //{
        //    var runsql = DbType.DB().Insert<T>().AppendData(models);
        //    return runsql.ExecuteAffrows();
        //}

        ///// <summary>
        ///// 修改方法
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //public virtual bool Update(T model)
        //{
        //    var runsql = DbType.DB().Update<T>().SetSource(model);
        //    var rows = runsql.ExecuteAffrows();
        //    return rows > 0;
        //}

        ///// <summary>
        ///// 删除方法
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //public virtual bool Delete(long id)
        //{
        //    var result = DbType.DB().Delete<T>(id).ExecuteAffrows();
        //    return result > 0;
        //}

        ///// <summary>
        ///// 获取一条数据
        ///// </summary>
        ///// <param name="where"></param>
        ///// <returns></returns>
        //public virtual T GetByOne(Expression<Func<T, bool>> where)
        //{
        //    return DbType.DB().Select<T>()
        //        .Where(where).ToOne();
        //}

        ///// <summary>
        ///// 查询方法
        ///// </summary>
        ///// <param name="where"></param>
        ///// <param name="orderby"></param>
        ///// <returns></returns>
        //public virtual (List<T> list, long count) Query(Expression<Func<T, bool>> where,
        //    List<SortInfo<T, object>> orderbys = null, PageInfo pageInfo = null)
        //{
        //    //设置查询条件
        //    var list = DbType.DB().Select<T>()
        //        .Where(where);


        //    var count = list.Count();

        //    BaseEntity baseEntity = new BaseEntity();
        //    //设置排序
        //    if (orderbys == null) list = list.OrderBy(s => s.CreateDt);
        //    else
        //    {
        //        foreach (var item in orderbys)
        //        {
        //            list = item.SortMethods == SortEnum.Asc ? list.OrderBy(item.Orderby) : list.OrderByDescending(item.Orderby);
        //        }
        //    }

        //    //设置分页操作
        //    if (pageInfo != null && pageInfo.IsPaging)
        //        list.Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize);
        //    var resultList = list.ToList();
        //    //执行查询
        //    return (resultList, count);
        //}
        //#endregion
    }

}
